package com.bolt.admin.security.shiro.realm;


import com.bolt.admin.module.sys.service.OnlineUserService;
import com.bolt.admin.module.sys.service.UserService;
import com.bolt.admin.security.shiro.AuthContextHolder;
import com.bolt.admin.security.shiro.AuthUserDetails;
import com.bolt.admin.security.shiro.DefaultAuthUserDetails;
import com.bolt.admin.security.shiro.OnlineBean;
import com.bolt.admin.security.shiro.exception.AuthErrorException;
import com.bolt.admin.security.shiro.jwt.TokenProvider;
import com.bolt.admin.security.shiro.jwt.UserInfo;
import com.bolt.admin.security.shiro.token.JWTToken;
import com.bolt.common.utils.SpringContextUtil;
import com.bolt.common.utils.StrUtil;
import com.bolt.convention.data.code.AuthCode;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import java.util.Objects;

/**
 * Created by Administrator on 2018/11/14.
 */
public class JWTTokenRealm extends AuthorizingRealm {

    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JWTToken;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) {
        JWTToken bearerToken = (JWTToken) authcToken;
        String accessToken = bearerToken.getAccessToken();
        TokenProvider tokenProvider = SpringContextUtil.getBean(TokenProvider.class);

        String accountId = tokenProvider.getUsernameFromToken(accessToken);

        OnlineUserService onlineUserService = SpringContextUtil.getBean(OnlineUserService.class);
        OnlineBean onlineUser = onlineUserService.getOne(accountId);
        if (Objects.isNull(onlineUser)) {
            throw new AuthErrorException(AuthCode.ACCESS_TOKEN_HAS_EXPIRED);
        }else{
            if (onlineUser != null && StrUtil.isNotBlank(accessToken)) {
                // Token 续期
                tokenProvider.checkRenewal(accessToken);
            }
        }
        UserService userService = SpringContextUtil.getBean(UserService.class);

        UserInfo userInfo = userService.userInfo(accountId);
        //构造权限框架认证用户信息对象
        DefaultAuthUserDetails authUserDetails = new DefaultAuthUserDetails();
        authUserDetails.setUserInfo(userInfo);
        authUserDetails.setKey(accessToken);
        return new SimpleAuthenticationInfo(authUserDetails, accessToken, getName());
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        AuthUserDetails userDetails = AuthContextHolder.getAuthUserDetails();

        UserService userService = SpringContextUtil.getBean(UserService.class);
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        UserInfo userInfo = userService.userInfo(userDetails.getUserId());
        info.setRoles(userInfo.getRoles());
        info.addStringPermissions(userInfo.getPermissions());

        return info;
    }
}
